home *** CD-ROM | disk | FTP | other *** search
/ Gekikoh Dennoh Club 7 / Gekikoh Dennoh Club Vol. 7 (Japan).7z / Gekikoh Dennoh Club Vol. 7 (Japan) (Track 01).bin / games / otoko / source.lzh / otoko.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-06-14  |  32.3 KB  |  1,346 lines

  1. /* 今は無き UPL と、ビデオゲームが好きだった自分に本作を捧げる */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <time.h>
  7. #include <sys/dos.h>
  8. #include <sys/iocs.h>
  9. #include <xsp2lib.h>
  10. #include <pcm8afnc.h>
  11. #include <apicglib.h>
  12.  
  13. #define GLOBAL_DEFINE        /* グローバル変数を確保する */
  14. #include "otoko.h"
  15. #include "player.h"
  16. #include "shot.h"
  17. #include "enemy.h"
  18. #include "eshot.h"
  19. #include "effect.h"
  20. #include "entry.h"
  21. #include "psearch.h"
  22. #include "txfont.h"
  23. #include "gvram.h"
  24. #include "sound.h"
  25.  
  26.  
  27. #define    PCG_MAX    668        /* スプライトPCGパターン最大使用数 */
  28. #define    REF_MAX    872        /* 複合スプライトリファレンスデータ最大使用数 */
  29. #define    FRM_MAX    22038        /* 複合スプライトフレームデータ最大使用数 */
  30. #define RGB(r,g,b) ((g)<<11|(r)<<6|(b)<<1)
  31.  
  32.  
  33. static char pcg_alt[PCG_MAX + 1];    /* PCG配置管理テーブル */
  34. static char pcg_dat[PCG_MAX * 128];    /* PCGデータファイル読み込みバッファ */
  35. static XOBJ_REF_DAT ref_dat[REF_MAX];    /* リファレンスデータ */
  36. static XOBJ_FRM_DAT frm_dat[FRM_MAX];    /* フレームデータ */
  37. static int old_crtmod;
  38.  
  39. static int sizeof_pcg = 0;    /* スプライトPCGパターン読み込み数 */
  40. static int sizeof_ref = 0;    /* 複合スプライトリファレンスデータ読み込み数 */
  41. static int sizeof_frm = 0;    /* 複合スプライトフレームデータ読み込み数 */
  42.  
  43.  
  44. static unsigned short blue_core[28][5];
  45. static unsigned short red_core[28][5];
  46.  
  47. static int high_score[10];
  48. static char high_score_name[10][4];
  49. static char high_score_date[10][11];    /* yyyy/mm/dd */
  50. static char high_score_changed = 0;    /* ハイスコアを書き出す必要があるか */
  51.  
  52. static int xsp_mode_num;
  53. static char n_option;
  54. static int y_option;        /* 開始面数-1 */
  55. static int z_option;        /* 残機数 */
  56.  
  57. #define    SAVE_GRPALET    32    /* 保存するパレット数(タイトルの「男」「弾」用) */
  58. static unsigned short grpalet[SAVE_GRPALET];
  59.  
  60. enum {
  61.     IN_TITLE = 0, IN_GAME, IN_GAME_OVER
  62. };
  63. static char game_state = IN_TITLE;
  64.  
  65. enum {
  66.     SELECT_START = 0, SELECT_REPLAY_BEFORE, SELECT_REPLAY_HIGH, SELECT_RANKING, SELECT_EXIT
  67. };
  68.  
  69. static int demo_state = SELECT_RANKING;
  70.  
  71.  
  72. #define WAIT_TIME    6
  73. #define WAIT_DEMO    (10*55)    /* タイトル画面でこれ以上操作されなかったらデモ */
  74.  
  75.  
  76. static void Usage (void)
  77. {
  78.     printf ("男のシューティング・男弾 otoko.x ver1.00\n"
  79.         "        programmed by Mitsuky <FreeSoftware>\n"
  80.         "使用法 : otoko [option]\n"
  81.         "[option]\n"
  82.     /* "    -E : エントリー編集モード\n"     */
  83.         "    -Sファイル名 : ハイスコア保存ファイルの指定\n"
  84.         "    -N : ハイスコアをファイルに保存しない\n"
  85.       "    -D数値 : 表示負荷 (数値 = 0~2(数値が大きいほど重い), デフォルト = 1)\n"
  86.         "    -X数値 : xsp_mode (数値 = 1~3, デフォルト = 2)\n"
  87.         "    -Y数値 : 開始面数\n(数値 = 1~4, デフォルト = 1)"
  88.         "    -Z数値 : 残機数(数値 = 1~9, デフォルト = 3)\n"
  89.         "ハイスコアは標準設定(開始面数 = 1, 残機数 = 3)時のみ記録されます\n"
  90.     );
  91. }
  92.  
  93.  
  94.  
  95. /* 垂直同期ごとに呼ばれるルーチン */
  96. static void VdispRoutine (void)
  97. {
  98.     static short pal = 0, pal2 = 0;
  99.     static short *b_ptr = &blue_core[0][0], *r_ptr = &red_core[0][0];
  100.     unsigned short *d;
  101.     static int y0, y1;
  102.  
  103.     switch (game_state) {
  104.     case IN_GAME:
  105.         /* コアを点滅させる */
  106.         pal2 = !pal2;
  107.         if (pal2) {
  108.             d = (unsigned short *) (0xe82200 + 4 * 16 * 2 + 2);
  109.             *d++ = *b_ptr++;
  110.             *d++ = *b_ptr++;
  111.             *d++ = *b_ptr++;
  112.             *d++ = *b_ptr++;
  113.             *d++ = *b_ptr++;
  114.         } else {
  115.             d = (unsigned short *) (0xe82200 + 5 * 16 * 2 + 2);
  116.             *d++ = *r_ptr++;
  117.             *d++ = *r_ptr++;
  118.             *d++ = *r_ptr++;
  119.             *d++ = *r_ptr++;
  120.             *d++ = *r_ptr++;
  121.             pal++;
  122.         }
  123.         if (pal > 27) {
  124.             pal = 0;
  125.             b_ptr = &blue_core[0][0];
  126.             r_ptr = &red_core[0][0];
  127.         }
  128.         if (pause_flag)
  129.             return;    /* ポーズ中ならここまで */
  130.  
  131.         /* ポーズ中でなければ行う処理 */
  132.         *(volatile unsigned int *) 0xe80018 = *(volatile unsigned int *) 0xe8001c = y0;
  133.         y0 -= 2;
  134.         y0 &= 511;
  135.  
  136.         *(volatile unsigned int *) 0xe80020 = *(volatile unsigned int *) 0xe80024 = y1;
  137.         if (stage != 0) {
  138.             y1 -= 4;
  139.             y1 &= 511;
  140.         } else {
  141.             y1 -= 2;
  142.             y1 &= 511;
  143.         }
  144.  
  145.         /* 背景のフェードイン/フェードアウト中か? */
  146.         switch (bg_contrast_control) {
  147.         case BG_NORMAL:/* 通常のゲーム時 */
  148.         case BG_DRAWING:    /* 背景描画中 */
  149.             break;
  150.  
  151.         case BG_FADEIN:/* フェードイン中 */
  152.             {
  153.                 unsigned short *s = bg_contrast_ptr;
  154.                 unsigned short *d = (unsigned short *) (0xe82000 + 16 * 2);
  155.                 unsigned short h = BG_PALETS / 4;    /* 処理するパレット数 */
  156.                 do {
  157.                     *d++ = *s++;
  158.                     *d++ = *s++;
  159.                     *d++ = *s++;
  160.                     *d++ = *s++;
  161.                 } while (--h);
  162.                 bg_contrast_ptr -= BG_PALETS;
  163.                 bg_contrast_num--;
  164.                 if (bg_contrast_num <= 0) {
  165.                     bg_contrast_control = BG_NORMAL;    /* フェードイン終了 */
  166.                     bg_contrast_ptr = &stage_palet_table[stage][0][0];
  167.                 } else {
  168.                     if (bg_contrast_num == 32)
  169.                         y0 = y1 = 0;    /* スクロール座標初期化 */
  170.                 }
  171.             }
  172.             break;
  173.         case BG_FADEOUT:    /* フェードアウト中 */
  174.             {
  175.                 unsigned short *s = bg_contrast_ptr;
  176.                 unsigned short *d = (unsigned short *) (0xe82000 + 16 * 2);
  177.                 unsigned short h = BG_PALETS / 4;    /* 処理するパレット数 */
  178.                 do {
  179.                     *d++ = *s++;
  180.                     *d++ = *s++;
  181.                     *d++ = *s++;
  182.                     *d++ = *s++;
  183.                 } while (--h);
  184.                 bg_contrast_ptr += BG_PALETS;
  185.                 bg_contrast_num--;
  186.                 if (bg_contrast_num <= 0) {
  187.                     bg_contrast_control = BG_NORMAL;    /* フェードアウト終了 */
  188.                     entry_counter_stop = 0;    /* エントリー再開 */
  189.                     *(unsigned short *) (0xe82000) = 0;
  190.                     d = (unsigned short *) (0xe82000 + 16 * 2);
  191.                     h = BG_PALETS / 4;
  192.                     do {
  193.                         *d++ = 0;
  194.                         *d++ = 0;
  195.                         *d++ = 0;
  196.                         *d++ = 0;
  197.                     } while (--h);
  198.                 }
  199.             }
  200.             break;
  201.         }
  202.  
  203.         /* ボンバーで背景が光っている時の処理 */
  204.         switch (player->bomb_flash_state) {
  205.         case BG_FLASH_NON:
  206.             break;
  207.         case BG_FLASH_WHITE:    /* 白フラッシュ */
  208.             {
  209.                 unsigned short *d = (unsigned short *) (0xe82000 + 16 * 2);
  210.                 unsigned short h = BG_PALETS / 4;    /* 処理するパレット数 */
  211.                 *(unsigned short *) (0xe82000) = RGB (24, 24, 24);    /* フラッシュ色 */
  212.                 do {
  213.                     *d++ = RGB (24, 24, 24);    /* フラッシュ色 */
  214.                     *d++ = RGB (24, 24, 24);
  215.                     *d++ = RGB (24, 24, 24);
  216.                     *d++ = RGB (24, 24, 24);
  217.                 } while (--h);
  218.             }
  219.             break;
  220.         case BG_FLASH_NORMAL:    /* 通常のパレット */
  221.             {
  222.                 unsigned short *s;
  223.                 unsigned short *d = (unsigned short *) (0xe82000 + 16 * 2);
  224.                 unsigned short h = BG_PALETS / 4;    /* 処理するパレット数 */
  225.  
  226.                 *(unsigned short *) (0xe82000) = 0;
  227.                 switch (bg_contrast_control) {
  228.                 case BG_NORMAL:
  229.                     s = &stage_palet_table[stage][0][0];
  230.                     do {
  231.                         *d++ = *s++;
  232.                         *d++ = *s++;
  233.                         *d++ = *s++;
  234.                         *d++ = *s++;
  235.                     } while (--h);
  236.                     break;
  237.                 case BG_DRAWING:
  238.                     do {
  239.                         *d++ = 0;
  240.                         *d++ = 0;
  241.                         *d++ = 0;
  242.                         *d++ = 0;
  243.                     } while (--h);
  244.                     break;
  245.                 case BG_FADEIN:
  246.                 case BG_FADEOUT:
  247.                     break;    /* 上の方で設定しているので必要無し */
  248.                 }
  249.             }
  250.             break;
  251.         }
  252.         break;
  253.  
  254.     case IN_TITLE:
  255.     case IN_GAME_OVER:
  256.         break;
  257.     }
  258. }
  259.  
  260.  
  261.  
  262. /* 終了時に1度だけ呼ばれる・エラーだったら返ってこない */
  263. void Tini (void)
  264. {
  265.     int sp;
  266.     char *error_message_table[]=
  267.     {
  268.         "Thanks for playing !\n",
  269.         "テキスト VRAM が使用中です\n",
  270.         "グラフィック VRAM が使用中です\n"
  271.     };
  272.  
  273.     if (error_level < ERROR_FILE)
  274.         error_message = error_message_table[error_level];
  275.  
  276.     switch (error_level) {
  277.     case ERROR_NON:
  278.     case ERROR_FILE:
  279.         _iocs_tgusemd (1, 0);
  280.     case ERROR_GUSEMD:
  281.         _iocs_tgusemd (0, 0);
  282.     case ERROR_TUSEMD:
  283.     default:
  284.         break;
  285.     }
  286.  
  287.  
  288.     xsp_vsyncint_off ();
  289.     pcm8a_vsyncint_off ();
  290.     xsp_off ();
  291.     SoundStop ();
  292.  
  293.     sp = _iocs_b_super (0);
  294.     *(unsigned short *) 0xe8e006 &= 0xfffd;    /* HRL ビット */
  295.     _iocs_b_super (sp);
  296.  
  297.     _iocs_skey_mod (-1, 0, 0);
  298.     _iocs_b_curon ();
  299.     _iocs_crtmod (old_crtmod);
  300.  
  301.     _dos_kflushio (0xff);    /* キーバッファをクリア */
  302.     printf ("%s", error_message);
  303.  
  304.     if (error_level > ERROR_NON)    /* エラーが発生した場合は */
  305.         exit (-1);    /* 終了する */
  306. }
  307.  
  308.  
  309.  
  310. /* 起動時のファイル読み込み */
  311. /* 読み込みに失敗した場合はいきなり終了するので注意 */
  312. static int LoadFile (char *fname, void *ptr, size_t size, size_t n)
  313. {
  314.     FILE *fp;
  315.     int i;
  316.  
  317.     if ((fp = fopen (fname, "rb")) == NULL) {
  318.         static char e[256];
  319.         error_level = ERROR_FILE;
  320.         error_message = e;
  321.         sprintf (e, "ファイル %s が読み込めません\n", fname);
  322.         Tini ();    /* 返ってこない */
  323.     }
  324.     i = fread (ptr, size, n, fp);
  325.     fclose (fp);
  326.  
  327.     return (i);        /* 返り値は読み込み項目数 */
  328. }
  329.  
  330.  
  331.  
  332. /* SP データ読み込み */
  333. static short LoadSP (char *fname)
  334. {
  335.     int p;
  336.     short sp_no = sizeof_pcg / 128;
  337.     char temp_fname[92];
  338.  
  339.     strcpy (temp_fname, fname);
  340.     strcat (temp_fname, ".SP");
  341.     p = LoadFile (temp_fname, &pcg_dat[sizeof_pcg], sizeof (char), 128 * PCG_MAX - sizeof_pcg);
  342.  
  343.     sizeof_pcg += p;
  344.  
  345. #ifdef DEBUG
  346.     printf ("%s を読み込みました sp_no = %hd\n", fname, sp_no);
  347. #endif
  348.     return (sp_no);
  349. }
  350.  
  351.  
  352.  
  353. /* XSP 各種データ読み込み */
  354. static short LoadXSP (char *fname)
  355. {
  356.     int i;
  357.     int p, f, r;
  358.     short obj_no = sizeof_ref;
  359.     char temp_fname[92];
  360.  
  361.     strcpy (temp_fname, fname);
  362.     strcat (temp_fname, ".FRM");
  363.     f = LoadFile (temp_fname, &frm_dat[sizeof_frm], sizeof (XOBJ_FRM_DAT), FRM_MAX - sizeof_frm);
  364.  
  365.     strcpy (temp_fname, fname);
  366.     strcat (temp_fname, ".REF");
  367.     r = LoadFile (temp_fname, &ref_dat[sizeof_ref], sizeof (XOBJ_REF_DAT), REF_MAX - sizeof_ref);
  368.  
  369.     strcpy (temp_fname, fname);
  370.     strcat (temp_fname, ".XSP");
  371.     p = LoadFile (temp_fname, &pcg_dat[sizeof_pcg], sizeof (char), 128 * PCG_MAX - sizeof_pcg);
  372.  
  373.     /* FRM_DAT[].pt 補正 */
  374.     for (i = 0; i < f; i++)
  375.         frm_dat[sizeof_frm + i].pt += sizeof_pcg / 128;
  376.  
  377.     /* REF_DAT[].ptr 補正 */
  378.     for (i = 0; i < r; i++)
  379.         (int) ref_dat[sizeof_ref + i].ptr += (int) (&frm_dat[sizeof_frm]);
  380.     sizeof_pcg += p;
  381.     sizeof_frm += f;
  382.     sizeof_ref += r;
  383.  
  384. #ifdef DEBUG
  385.     printf ("%s を読み込みました sizeof_ref = %hd\n", fname, obj_no);
  386. #endif
  387.  
  388.     return (obj_no);
  389. }
  390.  
  391.  
  392.  
  393. /* 起動時に1度だけ呼ばれる */
  394. static void Init (void)
  395. {
  396.     int i, sp;
  397.     unsigned short *s, *d;
  398.     unsigned short pal_dat[16 * 15];    /* パレットデータファイル読み込みバッファ */
  399.     unsigned short crtcdata[9] =
  400.     {69, 6, 11 + 8, 59 - 8, 567, 5, 40, 552, 0x0111};
  401.     unsigned short textpalet[16] =
  402.     {0, RGB (16, 16, 20), RGB (12, 12, 20), RGB (28, 28, 31), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  403.  
  404.     old_crtmod = _iocs_crtmod (-1);
  405.     error_message = NULL;
  406.  
  407.     error_level = ERROR_TUSEMD;
  408.     if (_iocs_tgusemd (1, -1) == 2)    /* テキスト画面の使用状況をチェック */
  409.         Tini ();
  410.  
  411.     error_level = ERROR_GUSEMD;
  412.     if (_iocs_tgusemd (0, -1))    /* グラフィック画面の使用状況をチェック */
  413.         Tini ();
  414.     _iocs_tgusemd (0, 2);
  415.     _iocs_tgusemd (1, 2);
  416.  
  417.     /* CD-ROM からの読み込みを速くするためにアルファベット順にソートしてたりして */
  418.     LoadFile ("DAT/ALPHA2.DAT", font_data, sizeof (char), 2048);
  419.     LoadFile ("DAT/STAGE01.DAT", &stage_data[0][0], sizeof (ENTRY), ENTRY_MAX);
  420.     LoadFile ("DAT/STAGE02.DAT", &stage_data[1][0], sizeof (ENTRY), ENTRY_MAX);
  421.     LoadFile ("DAT/STAGE03.DAT", &stage_data[2][0], sizeof (ENTRY), ENTRY_MAX);
  422.     LoadFile ("DAT/STAGE04.DAT", &stage_data[3][0], sizeof (ENTRY), ENTRY_MAX);
  423.  
  424.     LoadFile ("BG/STAGE01.MAP", &bg_map[0][0], sizeof (char), 30 + 32 * 128 * 2);
  425.     LoadFile ("BG/STAGE01.SP", &bg_sp[0][0], sizeof (char), 32 * 256);
  426.     LoadFile ("BG/STAGE01G.PAL", &stage_palet_table[0][0][0], sizeof (unsigned short), BG_PALETS * 33);
  427.     LoadFile ("BG/STAGE02.MAP", &bg_map[1][0], sizeof (char), 30 + 32 * 128 * 2);
  428.     LoadFile ("BG/STAGE02.SP", &bg_sp[1][0], sizeof (char), 32 * 256);
  429.     LoadFile ("BG/STAGE02G.PAL", &stage_palet_table[1][0][0], sizeof (unsigned short), BG_PALETS * 33);
  430.     LoadFile ("BG/STAGE03.MAP", &bg_map[2][0], sizeof (char), 30 + 32 * 128 * 2);
  431.     LoadFile ("BG/STAGE03.SP", &bg_sp[2][0], sizeof (char), 32 * 256);
  432.     LoadFile ("BG/STAGE03G.PAL", &stage_palet_table[2][0][0], sizeof (unsigned short), BG_PALETS * 33);
  433.     LoadFile ("BG/STAGE04.MAP", &bg_map[3][0], sizeof (char), 30 + 32 * 128 * 2);
  434.     LoadFile ("BG/STAGE04.SP", &bg_sp[3][0], sizeof (char), 32 * 256);
  435.     LoadFile ("BG/STAGE04G.PAL", &stage_palet_table[3][0][0], sizeof (unsigned short), BG_PALETS * 33);
  436.  
  437.     obj_bombstr = LoadXSP ("SP/BOMBSTR");
  438.     obj_blaser = LoadXSP ("SP/BLASER");
  439.     sp_core01 = LoadSP ("SP/CORE01");
  440.     obj_coverf = LoadXSP ("SP/COVERF");
  441.     obj_covern = LoadXSP ("SP/COVERN");
  442.     sp_cursor = LoadSP ("SP/CURSOR");
  443.     sp_eshot01 = LoadSP ("SP/ESHOT01");
  444.     sp_eshotera = LoadSP ("SP/ESHOTERA");
  445.     obj_explall = LoadXSP ("SP/EXPLALL");
  446.     obj_hahen = LoadXSP ("SP/HAHEN");
  447.     sp_laser01 = LoadSP ("SP/LASER01");
  448.     obj_lboss01 = LoadXSP ("SP/LBOSS01");
  449.     obj_lboss02 = LoadXSP ("SP/LBOSS02");
  450.     obj_lboss03 = LoadXSP ("SP/LBOSS03");
  451.     obj_lboss04 = LoadXSP ("SP/LBOSS04");
  452.     sp_lboss03g = LoadSP ("SP/LBOSS03G");
  453.     obj_mvlaser = LoadXSP ("SP/MVLASER");
  454.     obj_mvlaserh = LoadXSP ("SP/MVLASERH");
  455.     obj_oplaser = LoadXSP ("SP/OPLASER");
  456.     obj_player = LoadXSP ("SP/PLAYER");
  457.     obj_points = LoadXSP ("SP/POINTS");
  458.     obj_round4 = LoadXSP ("SP/ROUND4");
  459.     obj_searchz = LoadXSP ("SP/SEARCHZ");
  460.     obj_sword = LoadXSP ("SP/SWORD");
  461.     sp_shot = LoadSP ("SP/SHOT");
  462.     obj_titmoji = LoadXSP ("SP/TITMOJI");
  463.     obj_titspark = LoadXSP ("SP/TITSPARK");
  464.     obj_zako02 = LoadXSP ("SP/ZAKO02");
  465.     obj_zako03 = LoadXSP ("SP/ZAKO03");
  466.     obj_zako04 = LoadXSP ("SP/ZAKO04");
  467.  
  468. #ifdef DEBUG
  469.     printf ("    PCG 使用数 = %d\n    REF 使用数 = %d\n    FRM 使用数 = %d\n",
  470.         sizeof_pcg / 128, sizeof_ref, sizeof_frm);
  471. #endif
  472.  
  473.     LoadFile ("SP/OTOKO.PAL", pal_dat, 2, 16 * 15);
  474.  
  475.     LoadFile ("TBL/BLUECORE.PAL", blue_core, sizeof (unsigned short), 28 * 5);
  476.     LoadFile ("TBL/INFO_ROT.TBL", info_rot, sizeof (short), 256);
  477.     LoadFile ("TBL/PSTABLE.TBL", pstable, sizeof (unsigned char), 256 * 256);
  478.     LoadFile ("TBL/RNDTABLE.TBL", rndtable, sizeof (unsigned char), 256);
  479.     LoadFile ("TBL/REDCORE.PAL", red_core, sizeof (unsigned short), 28 * 5);
  480.     LoadFile ("TBL/PT_ROT.TBL", pt_rot, sizeof (short), 256);
  481.     LoadFile ("TBL/VXTABLE.TBL", vxtable, sizeof (signed int), 256 * SPEED_MAX);
  482.     LoadFile ("TBL/VYTABLE.TBL", vytable, sizeof (signed int), 256 * SPEED_MAX);
  483.  
  484.  
  485.     /* 画面モード設定 */
  486.     _iocs_crtmod (10);    /* 256*256dot 31kHz 256色 */
  487.     _iocs_g_clr_on ();
  488.     _iocs_b_curoff ();
  489.     _iocs_ms_curof ();
  490.     _iocs_skey_mod (0, 0, 0);
  491.  
  492.     _iocs_sp_init ();
  493.     _iocs_sp_on ();        /* スプライト表示をON */
  494.     _iocs_bgctrlst (0, 0, 0);    /* BG0表示OFF */
  495.     _iocs_bgctrlst (1, 1, 0);    /* BG1表示OFF */
  496.  
  497.     /* 256x256 正方形モードを作る */
  498.     sp = _iocs_b_super (0);
  499.     *(unsigned short *) 0xe80028 = crtcdata[8];
  500.     d = (unsigned short *) 0xe80002;
  501.     for (i = 1; i < 8; i++)
  502.         *d++ = crtcdata[i];
  503.     *(unsigned short *) 0xe80000 = crtcdata[0];
  504.  
  505.     *(unsigned short *) 0xe8e006 |= 0b10;    /* HRL ビット */
  506.     *(unsigned short *) 0xeb080c = crtcdata[2] + 4;
  507.     *(unsigned short *) 0xeb080a = crtcdata[0];    /* スプライト */
  508.     *(unsigned short *) 0xeb080e = crtcdata[6];
  509.     *(volatile unsigned int *) 0xe80018 = *(volatile unsigned int *) 0xe8001c
  510.         = *(volatile unsigned int *) 0xe80020 = *(volatile unsigned int *) 0xe80024
  511.         = (256 << 16) + 256;
  512.  
  513.     *(unsigned short *) 0xe82500 = 0b01001001001110;    /* 優先順位 TX>SP>GR */
  514.  
  515.  
  516.     /* タイトルの.PIC ファイルを読み込む */
  517.     {
  518.         unsigned char *file_buf, *work_buf;
  519.         int r;
  520.         error_level = ERROR_PIC_MEMORY;
  521. #define    PIC_FILE_BUF_SIZE    (16*1024)
  522.         file_buf = _dos_malloc (PIC_FILE_BUF_SIZE);
  523.         //work_buf = _dos_malloc (512 * 1024);
  524.         work_buf = _dos_malloc (128 * 256);
  525.         if (((int) file_buf < 0) || ((int) work_buf < 0)) {
  526.             static char e[256];
  527.             printf ("メモリエラー\n");
  528.             error_level = ERROR_PIC_MEMORY;
  529.             error_message = e;
  530.             strcpy (e, ".PIC 展開用メモリが足りません\n");
  531.             Tini ();/* 返ってこない */
  532.         } else {
  533.             error_level = ERROR_PIC_FILE;
  534.             r = APICLOAD ((unsigned short *) 0xc00000, "SP/OTOKO.PIC", 256, 0,
  535.                       file_buf, PIC_FILE_BUF_SIZE, APF_NOINITCRT | APF_NOCLRBUF | APF_NOPRFC, work_buf);
  536.             if (r < 0) {
  537.                 static char e[256];
  538.                 error_level = ERROR_PIC_FILE;
  539.                 error_message = e;
  540.                 strcpy (e, "SP/OTOKO.PIC が読み込めません\n");
  541.                 Tini ();    /* 返ってこない */
  542.             }
  543.             r = APICLOAD ((unsigned short *) 0xc00000, "SP/DAMA.PIC",
  544.             /* ロード座標をこうする事により 256色モードのページ1に読み込む */
  545.             /* (素直にアドレスを 0xc80000 にすると読めないみたい) */
  546.                       256, 512 + 128,    /* ロードX/Y座標 */
  547.                       file_buf, PIC_FILE_BUF_SIZE, APF_NOINITCRT | APF_NOCLRBUF | APF_NOPRFC, work_buf);
  548.             if (r < 0) {
  549.                 static char e[256];
  550.                 error_level = ERROR_PIC_FILE;
  551.                 error_message = e;
  552.                 strcpy (e, "SP/DAMA.PIC が読み込めません\n");
  553.                 Tini ();    /* 返ってこない */
  554.             }
  555.             _dos_mfree (work_buf);
  556.             _dos_mfree (file_buf);
  557.         }
  558.     }
  559.  
  560.     /* グラフィック画面のパレットを保存 */
  561.     {
  562.         unsigned short *p = (unsigned short *) (0xe82000 + (256 - SAVE_GRPALET) * 2);
  563.         for (i = 0; i < SAVE_GRPALET; i++)
  564.             grpalet[i] = *p++;
  565.     }
  566.  
  567.     error_level = ERROR_MUSIC;
  568.  
  569.     /* パレットに転送 */
  570.     s = (unsigned short *) 0xe82200;
  571.     for (i = 0; i < 16; i++)
  572.         *s++ = textpalet[i];
  573.     d = pal_dat;
  574.     for (i = 0; i < 15 * 16; i++)
  575.         *s++ = *d++;
  576.     _iocs_b_super (sp);
  577.  
  578.     /* 一般的な初期化 */
  579.     EntryInit0 ();
  580.     PlayerInit0 ();
  581.     ShotInit0 ();
  582.     EnemyInit0 ();
  583.     EshotInit0 ();
  584.     EffectInit0 ();
  585.     TxfontInit0 ();
  586.     SoundInit0 ();
  587.  
  588.  
  589.     _dos_breakck (2);    /* BREAK チェックを殺す */
  590.     _dos_intvcs (0xfff1, Tini);    /* _CTRLVC */
  591.     _dos_intvcs (0xfff2, Tini);    /* _ERRJVC */
  592.  
  593.     xsp_on ();
  594.     xsp_mode (xsp_mode_num);
  595.     xsp_pcgdat_set (pcg_dat, pcg_alt, sizeof (pcg_alt));
  596.     xsp_objdat_set (ref_dat);
  597.     xsp_vsyncint_on (&VdispRoutine);
  598.     pcm8a_vsyncint_on ();
  599.  
  600.     sp = _iocs_b_super (0);
  601.     *(unsigned short *) 0xe82600 |= 0x007f;    /* 画面表示オン */
  602.     _iocs_b_super (sp);
  603.  
  604.  
  605.  
  606.     error_level = ERROR_NON;
  607.     return;
  608. }
  609.  
  610.  
  611.  
  612.  
  613. static void TextClear (void)
  614. {
  615.     _iocs_txrascpy (256 / 4 * 256, 256 / 4, 0b1111);    /* テキスト画面クリア */
  616. }
  617.  
  618.  
  619. /* ボタンが押されるか timer フレーム経つまで待つ */
  620. static void WaitTime (int timer)
  621. {
  622.     int t = timer;
  623.     while ((_iocs_joyget (0) & 0x60) != 0x60);
  624.     do {
  625.         xsp_vsync (1);
  626.         if ((_iocs_joyget (0) & 0x60) != 0x60)
  627.             break;
  628.     } while (t--);
  629.     while ((_iocs_joyget (0) & 0x60) != 0x60);
  630. }
  631.  
  632.  
  633. /* グラフィック画面のパレットを半分の明るさに */
  634. static void HalfColor (void)
  635. {
  636.     unsigned short *p = (unsigned short *) (0xe82000 + (256 - SAVE_GRPALET) * 2);
  637.     int i, sp;
  638.  
  639.     sp = _iocs_b_super (0);
  640.     for (i = 0; i < SAVE_GRPALET; i++) {
  641.         unsigned short c, r, g, b;
  642.         c = grpalet[i];
  643.         r = ((c >> 6) & 31) / 2;
  644.         g = ((c >> 11) & 31) / 2;
  645.         b = ((c >> 1) & 31) / 2;
  646.         *p++ = (((((g << 5) | r) << 5) | b) << 1);
  647.     }
  648.     _iocs_b_super (sp);
  649. }
  650.  
  651.  
  652. /* ハイスコア表示 */
  653. static void Ranking (void)
  654. {
  655.     short h;
  656.     char temp_str[64];
  657.  
  658.     TextClear ();
  659.     TxfontCursor (8, 3);
  660.     TxfontPuts ("HARDCORE SHOOTERS");
  661.  
  662. #define    RANK_X    3
  663. #define    RANK_Y    7
  664.     for (h = 0; h < 10; h++) {
  665.         sprintf (temp_str, "%2hd  %s %06d  %s",
  666.              h + 1, &high_score_name[h], high_score[h], &high_score_date[h]);
  667.         TxfontCursor (RANK_X, h * 2 + RANK_Y);
  668.         TxfontPuts (temp_str);
  669.     }
  670. }
  671.  
  672.  
  673.  
  674. /* ハイスコアネームエントリー */
  675. static void NameEntry (short rank)
  676. {
  677.     char temp[4];
  678.     char ch = 'A';
  679.     int cx = 0;        /* カーソル位置 */
  680.     time_t now;
  681.     struct tm *tloc;
  682.  
  683.     enum {
  684.         JOY_NON = 0, JOY_LEFT, JOY_RIGHT
  685.     };
  686.  
  687.     if (rank != 9) {
  688.         short h;
  689.         /* ハイスコアを1つづつずらす */
  690.         for (h = 9; h > rank; h--) {
  691.             high_score[h] = high_score[h - 1];
  692.             strcpy (high_score_name[h], high_score_name[h - 1]);
  693.             strcpy (high_score_date[h], high_score_date[h - 1]);
  694.         }
  695.     }
  696.     high_score[rank] = score;
  697.     strcpy (high_score_name[rank], "A__");
  698.     now = time (NULL);
  699.     tloc = localtime (&now);
  700.     sprintf (high_score_date[rank], "%4d/%02d/%02d",
  701.          tloc->tm_year + 1900, tloc->tm_mon + 1, tloc->tm_mday);
  702.  
  703.     Ranking ();
  704.     HalfColor ();
  705.  
  706.     high_score_changed = !0;
  707.     if (rank == 0) {
  708.         int i;
  709.         int *p1 = (unsigned int *) (&replay_data[0]), *p2 = (unsigned int *) (&high_score_replay_data[0]);
  710.         SoundMusic (MUSIC_RANKING_1ST);    /* 1位の時 */
  711.         /* 今回のリプレイデータをハイスコアのリプレイデータにコピー */
  712.         high_score_replay_data_size = player->replay_counter;
  713.         for (i = 0; i < (high_score_replay_data_size + 15) / 16; i++) {
  714.             *p2++ = *p1++;
  715.             *p2++ = *p1++;
  716.             *p2++ = *p1++;
  717.             *p2++ = *p1++;
  718.         }
  719.     } else {
  720.         SoundMusic (MUSIC_RANKING_2ND);
  721.     }
  722.  
  723. #define RANK_NAME_X    (RANK_X+4)
  724.  
  725.     for (cx = 0; cx < 3; cx++) {
  726.         int old_t = JOY_NON, ct = 0, ct2 = 0;
  727.         TxfontCursor (RANK_NAME_X + cx, RANK_Y + rank * 2);
  728.         TxfontPutchar (ch);
  729.         for (;;) {
  730.             int t;
  731.             xsp_vsync (1);
  732.             t = _iocs_joyget (0);
  733.             if ((t & 0b0100) == 0) {    /* 左 */
  734.                 if (old_t != JOY_LEFT) {
  735.                     if (--ch < ' ')
  736.                         ch = '_';
  737.                     TxfontCursor (RANK_NAME_X + cx, RANK_Y + rank * 2);
  738.                     TxfontPutchar (ch);
  739.                     old_t = JOY_LEFT;
  740.                     ct = ct2 = 0;
  741.                 } else {
  742.                     if (ct++ > WAIT_TIME) {
  743.                         old_t = JOY_NON;
  744.                         ct = 0;
  745.                     }
  746.                 }
  747.             }
  748.             if ((t & 0b1000) == 0) {    /* 右 */
  749.                 if (old_t != JOY_RIGHT) {
  750.                     if (++ch > 'Z')
  751.                         ch = ' ';
  752.                     TxfontCursor (RANK_NAME_X + cx, RANK_Y + rank * 2);
  753.                     TxfontPutchar (ch);
  754.                     old_t = JOY_RIGHT;
  755.                     ct = ct2 = 0;
  756.                 } else {
  757.                     if (ct++ > WAIT_TIME) {
  758.                         old_t = JOY_NON;
  759.                         ct = 0;
  760.                     }
  761.                 }
  762.             }
  763.             if ((t & 0b1111) == 0b1111) {
  764.                 old_t = JOY_NON;
  765.                 ct = 0;
  766.                 ct2++;
  767.                 switch (ct2) {
  768.                 case 30:
  769.                     TxfontCursor (RANK_NAME_X + cx, RANK_Y + rank * 2);
  770.                     TxfontPutchar ('_');
  771.                     break;
  772.                 case 50:
  773.                     TxfontCursor (RANK_NAME_X + cx, RANK_Y + rank * 2);
  774.                     TxfontPutchar (ch);
  775.                     break;
  776.                 case 60:
  777.                     ct2 = 0;
  778.                     break;
  779.                 default:
  780.                     break;
  781.                 }
  782.             }
  783.             if ((t & 0b01000000) == 0) {    /* button B */
  784.                 while ((_iocs_joyget (0) & 0b01000000) == 0);
  785.                 TxfontCursor (RANK_NAME_X + cx, RANK_Y + rank * 2);
  786.                 TxfontPutchar (ch);
  787.                 temp[cx] = ch;
  788.                 ct2 = 0;
  789.                 break;
  790.             }
  791.             if ((t & 0b00100000) == 0) {    /* button A */
  792.                 while ((_iocs_joyget (0) & 0b00100000) == 0);
  793.                 if (cx != 0) {
  794.                     TxfontCursor (RANK_NAME_X + cx, RANK_Y + rank * 2);
  795.                     TxfontPutchar ('_');
  796.                     cx--;
  797.                     ch = temp[cx];
  798.                     TxfontCursor (RANK_NAME_X + cx, RANK_Y + rank * 2);
  799.                     TxfontPutchar (ch);
  800.                     ct2 = 0;
  801.                 }
  802.             }
  803.         }
  804.     }
  805.     temp[3] = 0;
  806.     strcpy (high_score_name[rank], temp);
  807.     SoundFadeOut (32);
  808.     WaitTime (55 * 5);
  809. }
  810.  
  811.  
  812.  
  813.  
  814. static void Game (void)
  815. {
  816.     char temp_str[32];
  817.     int sprites;        /* スプライト枚数 */
  818.     int old_score = -1;    /* 初回は必ず表示されるように */
  819.  
  820.     TextClear ();
  821.     EntryInit ();
  822.     PlayerInit ();
  823.     EnemyInitStatic ();
  824.     SoundStop ();
  825.  
  826.     if (standard_play)
  827.         sprintf (temp_str, "HI %06d", high_score[0]);
  828.     else
  829.         sprintf (temp_str, "HI ------");    /* ハイスコア集計なし */
  830.     TxfontCursor (21, 0);
  831.     TxfontPuts (temp_str);
  832.  
  833.     score = 0;
  834.     extend_score = EXTEND_EVERY;
  835.     stage = y_option;
  836.     player->rest = z_option;
  837.     pause_flag = 0;
  838.     game_state = IN_GAME;
  839.     DispRest ();        /* 残機数表示 */
  840.  
  841.     do {
  842.         EntryMove ();
  843.         PlayerMove ();
  844.         ShotMove ();
  845.         EnemyMove ();
  846.         EshotMove ();
  847.         EffectMove ();
  848.         GvramMove ();
  849.         SoundMove ();
  850.         sprites = xsp_out ();
  851.  
  852. #define    SCORE_X    2
  853. #define    SCORE_Y    0
  854.         if (score != old_score) {    /* 更新された時のみ表示 */
  855.             old_score = score;
  856.             sprintf (temp_str, "SCORE %06d", score);
  857.             TxfontCursor (SCORE_X, SCORE_Y);
  858.             TxfontPuts (temp_str);
  859.         }
  860. #ifdef DEBUG
  861.         //sprintf (temp_str, "SPRITES %06d", sprites);
  862.         //TxfontCursor (0, 1);
  863.         //TxfontPuts (temp_str);
  864.         sprintf (temp_str, "ESHOT  %03hd", eshot_sum);
  865.         TxfontCursor (0, 2);
  866.         TxfontPuts (temp_str);
  867.         sprintf (temp_str, "ENEMY  %03hd", enemy_sum);
  868.         TxfontCursor (0, 3);
  869.         TxfontPuts (temp_str);
  870. #endif
  871.     } while (player->game_over == GAME_PLAY);
  872.     EntryTini ();
  873.     PlayerTini ();
  874.     ShotTini ();
  875.     EnemyTini ();
  876.     EshotTini ();
  877.     EffectTini ();
  878.     GvramTini ();
  879.     SoundTini ();
  880.  
  881.     game_state = IN_GAME_OVER;
  882.     switch (player->game_over) {
  883.     case GAME_OVER:
  884.         TxfontCursor (11, 14);
  885.         TxfontPuts ("GAME OVER");
  886.         SoundMusic (MUSIC_GAME_OVER);
  887.         WaitTime (55 * 10);
  888.         break;
  889.     case GAME_COMPLETE:
  890.         while (--player->rest > 0) {
  891.             score += 5000;    /* 残機1機につき 5000pts */
  892.             DispRest ();    /* 残機数表示 */
  893.             sprintf (temp_str, "SCORE %06d", score);
  894.             TxfontCursor (SCORE_X, SCORE_Y);
  895.             TxfontPuts (temp_str);
  896.             if (player->rest > 1)
  897.                 WaitTime (30);
  898.             xsp_out ();
  899.         }
  900.         TxfontCursor (11, 14);
  901.         TxfontPuts (" COMPLETE");
  902.         SoundMusic (MUSIC_GAME_OVER);
  903.         WaitTime (55 * 10);
  904.         break;
  905.     case GAME_ABORT:
  906.     default:
  907.         break;
  908.     }
  909.     xsp_out ();        /* スプライトを消去 */
  910.  
  911.     /* 標準設定の時のみハイスコアを集計 */
  912.     if ((replay_flag == REPLAY_NON) && (standard_play)) {
  913.         replay_data_size = player->replay_counter;
  914.  
  915.         if ((player->game_over == GAME_OVER) || (player->game_over == GAME_COMPLETE)) {
  916.             short h, rank = 0;
  917.  
  918.             for (h = 0; h < 10; h++) {
  919.                 if (score <= high_score[h])
  920.                     rank = h + 1;
  921.             }
  922.             /* 1位なら rank=0, 11位なら rank=10 */
  923.             if (rank < 10)
  924.                 NameEntry (rank);
  925.         }
  926.     }
  927.     return;
  928. }
  929.  
  930.  
  931.  
  932. /* タイトル画面の表示 */
  933. static int Title (void)
  934. {
  935.     int cy = 0;        /* カーソル位置 */
  936.     int old_t, ct, ct2;
  937.     int t;
  938.     int sp;
  939.     short y_table[20] =
  940.     {
  941.         112, 96, 80, 64, 48, 32, 16, 0, 0, 3, 3, 1, 1, 2, 1, 0, 1, 1, 0, 0
  942.     };
  943.     enum {
  944.         JOY_NON = 0, JOY_UP, JOY_DOWN
  945.     };
  946.  
  947.     game_state = IN_TITLE;
  948.  
  949.     /* グラフィック画面のパレットを元に戻す */
  950.     {
  951.         unsigned short *p = (unsigned short *) (0xe82000 + (256 - SAVE_GRPALET) * 2);
  952.         int i;
  953.         sp = _iocs_b_super (0);
  954.         xsp_vsync (1);
  955.         *(unsigned short *) 0xe82600 &= 0xff80;    /* 画面表示オフ */
  956.         *(volatile unsigned int *) 0xe80018 = *(volatile unsigned int *) 0xe8001c
  957.             = *(volatile unsigned int *) 0xe80020 = *(volatile unsigned int *) 0xe80024
  958.             = (256 << 16) + 256;
  959.         for (i = 0; i < SAVE_GRPALET; i++)
  960.             *p++ = grpalet[i];
  961.         xsp_vsync (1);
  962.         *(unsigned short *) 0xe82600 |= 0x007f;    /* 画面表示オン */
  963.         _iocs_b_super (sp);
  964.     }
  965.     TextClear ();
  966.  
  967.     /* 男と弾の合体 */
  968.     {
  969.         short seq = 0;
  970.         char exit_flag = 0;
  971.         short h = 0;
  972.  
  973.         do {
  974.             xsp_out ();
  975.             if ((_iocs_joyget (0) & 0x60) != 0x60)
  976.                 break;
  977.             switch (seq) {
  978.             case 0:/* 「男」が落ちてくる */
  979.                 sp = _iocs_b_super (0);
  980.                 *(volatile unsigned int *) 0xe80018 = *(volatile unsigned int *) 0xe8001c
  981.                     = (256 << 16) + y_table[h];
  982.                 *(volatile unsigned int *) 0xe80020 = *(volatile unsigned int *) 0xe80024
  983.                     = (256 << 16) + 256;
  984.                 _iocs_b_super (sp);
  985.                 h++;
  986.                 if (h == 7) {
  987.                     EffectInit (EFFECT_TITSPARK, 0, 128 + 16, 128 + 16);
  988.                     SoundSetSE (SE_LOCK_M);
  989.                 }
  990.                 if (h > 18) {
  991.                     seq++;
  992.                     h = 0;
  993.                 }
  994.                 break;
  995.             case 1:/* 「弾」が上がってくる */
  996.                 sp = _iocs_b_super (0);
  997.                 *(volatile unsigned int *) 0xe80020 = *(volatile unsigned int *) 0xe80024
  998.                     = (256 << 16) + ((-y_table[h]) & 511);
  999.                 _iocs_b_super (sp);
  1000.                 h++;
  1001.                 if (h == 7) {
  1002.                     EffectInit (EFFECT_TITSPARK, 1, 128 + 16, 128 + 16);
  1003.                     SoundSetSE (SE_LOCK_M);
  1004.                 }
  1005.                 if (h > 18) {
  1006.                     seq++;
  1007.                     h = 0;
  1008.                     EffectInit (EFFECT_TITMOJI, 0, 0, 0);
  1009.                 }
  1010.                 break;
  1011.             case 2:/* 左右から「OTOKO」「DAMA」が */
  1012.                 if (h++ > 7) {
  1013.                     seq++;
  1014.                     for (h = 0; h < 6; h++)
  1015.                         EffectInit (EFFECT_EXPL, 0, rndtable[h] / 2 + 64 + 16, rndtable[h + 128] / 2 + 64 + 16);
  1016.                     EffectInit (EFFECT_EXPL, 0, 128 + 16, 128 + 16);
  1017.                     SoundSetSE (SE_EXPL_L);    /* ボスキャラ爆発音 */
  1018.                     h = 0;
  1019.                 }
  1020.                 break;
  1021.             case 3:
  1022.                 switch (h++) {
  1023.                 case 0:
  1024.                 case 3:
  1025.                 case 6:
  1026.                 case 9:
  1027. #define FLASH_PALET    224
  1028.                     /* パレットを白くフラッシュ */
  1029.                     sp = _iocs_b_super (0);
  1030.                     *(unsigned short *) (0xe82000 + FLASH_PALET * 2) = RGB (24, 24, 24);
  1031.                     _iocs_b_super (sp);
  1032.                     break;
  1033.                 case 0 + 1:
  1034.                 case 3 + 1:
  1035.                 case 6 + 1:
  1036.                 case 9 + 1:
  1037.                     /* パレットを復帰 */
  1038.                     sp = _iocs_b_super (0);
  1039.                     *(unsigned short *) (0xe82000 + FLASH_PALET * 2) = RGB (0, 0, 0);
  1040.                     _iocs_b_super (sp);
  1041.                     break;
  1042.                 case 56:
  1043.                     exit_flag = !0;
  1044.                     break;
  1045.                 default:
  1046.                     break;
  1047.                 }
  1048.                 break;
  1049.             default:
  1050.                 break;
  1051.             }
  1052.             EffectMove ();
  1053.             SoundMove ();
  1054.             if (seq > 2) {
  1055.                 xobj_set (128 + 16 + 16, 128 + 16, obj_titmoji, 0x0130);    /* OTOKO */
  1056.                 xobj_set (128 + 16 + 16, 128 + 16, obj_titmoji + 1, 0x0130);    /* DAMA */
  1057.             }
  1058.         } while (exit_flag == 0);
  1059.         xsp_out ();
  1060.         if (exit_flag != 0)
  1061.             WaitTime (3 * 55);
  1062.     }
  1063.     xobj_set (128 + 16 + 16, 128 + 16, obj_titmoji, 0x0130);    /* OTOKO */
  1064.     xobj_set (128 + 16 + 16, 128 + 16, obj_titmoji + 1, 0x0130);    /* DAMA */
  1065.     SoundMove ();
  1066.     EffectTini ();
  1067.     xsp_out ();
  1068.     sp = _iocs_b_super (0);
  1069.     *(volatile unsigned int *) 0xe80018 = *(volatile unsigned int *) 0xe8001c
  1070.         = *(volatile unsigned int *) 0xe80020 = *(volatile unsigned int *) 0xe80024
  1071.         = (256 << 16) + 0;
  1072.     *(unsigned short *) (0xe82000 + FLASH_PALET * 2) = RGB (0, 0, 0);
  1073.     _iocs_b_super (sp);
  1074.     while ((_iocs_joyget (0) & 0x60) != 0x60);
  1075.  
  1076.  
  1077.     HalfColor ();
  1078.  
  1079. #define    START_X    10        /* "START" を表示する座標 */
  1080. #define    START_Y    20
  1081.  
  1082.     TxfontCursor (0, 26);
  1083.     TxfontPuts (
  1084.                " (C)PROGRAMMED BY MITSUKY 1999\n"
  1085.                "     GRAPHICS BY H.SUZUKI\n\n"
  1086.                " FOR GEKIKOH-DENNOU CLUB VOL.7\n");
  1087.     TxfontCursor (0, START_Y);
  1088.     TxfontPuts (
  1089.                "        START\n"
  1090.                "        REPLAY\n"
  1091.                "        REPLAY HIGH\n"
  1092.                "        RANKING\n"
  1093.                "        EXIT\n"
  1094.         );
  1095.     TxfontCursor (START_X, START_Y + cy);
  1096.     TxfontPutchar ('>');
  1097.  
  1098.     old_t = JOY_NON;
  1099.     ct = ct2 = 0;
  1100.     do {
  1101.         xsp_vsync (1);
  1102.         t = _iocs_joyget (0);
  1103.         if (((t & 0b0001) == 0) && (cy > 0)) {    /* 上 */
  1104.             ct2 = 0;
  1105.             if (old_t != JOY_UP) {
  1106.                 TxfontCursor (START_X, START_Y + cy);
  1107.                 TxfontPutchar (' ');
  1108.                 if (standard_play) {
  1109.                     cy--;
  1110.                 } else {
  1111.                     if (cy == SELECT_RANKING)
  1112.                         cy = SELECT_START;
  1113.                     else
  1114.                         cy--;
  1115.                 }
  1116.                 TxfontCursor (START_X, START_Y + cy);
  1117.                 TxfontPutchar ('>');
  1118.                 old_t = JOY_UP;
  1119.                 ct = 0;
  1120.             } else {
  1121.                 if (ct++ > WAIT_TIME) {
  1122.                     old_t = JOY_NON;
  1123.                     ct = 0;
  1124.                 }
  1125.             }
  1126.         }
  1127.         if (((t & 0b0010) == 0) && (cy < 4)) {    /* 下 */
  1128.             ct2 = 0;
  1129.             if (old_t != JOY_DOWN) {
  1130.                 TxfontCursor (START_X, START_Y + cy);
  1131.                 TxfontPutchar (' ');
  1132.                 if (standard_play) {
  1133.                     cy++;
  1134.                 } else {
  1135.                     if (cy == SELECT_START)
  1136.                         cy = SELECT_RANKING;
  1137.                     else
  1138.                         cy++;
  1139.                 }
  1140.                 TxfontCursor (START_X, START_Y + cy);
  1141.                 TxfontPutchar ('>');
  1142.                 old_t = JOY_DOWN;
  1143.                 ct = 0;
  1144.             } else {
  1145.                 if (ct++ > WAIT_TIME) {
  1146.                     old_t = JOY_NON;
  1147.                     ct = 0;
  1148.                 }
  1149.             }
  1150.         }
  1151.         if ((t & 0b1111) == 0b1111) {
  1152.             old_t = JOY_NON;
  1153.             ct = 0;
  1154.         }
  1155.         if ((standard_play) && (ct2++ > WAIT_DEMO)) {    /* 一定時間操作が無ければデモ */
  1156.             ct2 = 0;
  1157.             cy = demo_state;
  1158.             demo_state++;
  1159.             if (demo_state > SELECT_RANKING)
  1160.                 demo_state = SELECT_REPLAY_BEFORE;
  1161.             break;
  1162.         }
  1163.         if (_iocs_bitsns (0x0c) & 0b10) {    /* [BREAK] */
  1164.             while (_iocs_bitsns (0x0c) & 0b10);
  1165.             cy = SELECT_EXIT;
  1166.             break;
  1167.         }
  1168.     } while ((t & 0b01000000) != 0);
  1169.     while ((_iocs_joyget (0) & 0b01000000) == 0);
  1170.     xsp_out ();
  1171.  
  1172.     return (cy);
  1173. }
  1174.  
  1175.  
  1176.  
  1177. /* ハイスコアデータの読み込み(なければ初期化) */
  1178. static void ReadHighScore (char *fname)
  1179. {
  1180.     int i;
  1181.     FILE *fp;
  1182.  
  1183.     replay_data_size = high_score_replay_data_size = 0;
  1184.     if ((fp = fopen (fname, "rb")) == NULL) {
  1185.         /* 読み込めなかった時は新規に */
  1186.         for (i = 0; i < 10; i++) {
  1187.             high_score[i] = (10 - i) * 1000;
  1188.             strcpy (high_score_name[i], "X68");
  1189.             sprintf (high_score_date[i], "1999/06/14");
  1190.         }
  1191.     } else {
  1192.         for (i = 0; i < 10; i++) {
  1193.             fread (&high_score[i], sizeof (int), 1, fp);
  1194.             fread (&high_score_name[i], sizeof (char), 4, fp);
  1195.             fread (&high_score_date[i], sizeof (char), 11, fp);
  1196.         }
  1197.         fread (&high_score_replay_data_size, sizeof (int), 1, fp);
  1198.         fread (&high_score_replay_data[0], sizeof (unsigned char), high_score_replay_data_size, fp);
  1199.         fclose (fp);
  1200.     }
  1201. }
  1202.  
  1203.  
  1204.  
  1205. /* ハイスコアデータの書き込み */
  1206. static void WriteHighScore (char *fname)
  1207. {
  1208.     int i;
  1209.     FILE *fp;
  1210.  
  1211.     if ((n_option == 0) && (high_score_changed) &&
  1212.         ((fp = fopen (fname, "wb")) != NULL)) {
  1213.         for (i = 0; i < 10; i++) {
  1214.             fwrite (&high_score[i], sizeof (int), 1, fp);
  1215.             fwrite (&high_score_name[i], sizeof (char), 4, fp);
  1216.             fwrite (&high_score_date[i], sizeof (char), 11, fp);
  1217.         }
  1218.         fwrite (&high_score_replay_data_size, sizeof (int), 1, fp);
  1219.         fwrite (&high_score_replay_data[0], sizeof (unsigned char), high_score_replay_data_size, fp);
  1220.         fclose (fp);
  1221.     }
  1222. }
  1223.  
  1224.  
  1225.  
  1226. int main (int argc, char *argv[])
  1227. {
  1228.     int i;
  1229.     int slash_flag = 0, exit_flag = 0;
  1230.     static char *save_file = "OTOKO.DAT";
  1231.  
  1232.     xsp_mode_num = 2;
  1233.     disp_level = 1;
  1234.     y_option = 0;
  1235.     z_option = 3;        /* デフォルトの残機数 */
  1236.     e_option = 0;
  1237.     n_option = 0;
  1238.  
  1239.     {
  1240.         char *temp;
  1241.  
  1242.         temp = getenv ("SLASH");
  1243.         if ((temp != NULL) && (*temp == '/')) {
  1244.             slash_flag = 1;
  1245.         }
  1246.     }
  1247.  
  1248.     for (i = 1; i < argc; i++) {
  1249.         if (('-' == *argv[i]) || ((slash_flag == 0) && ('/' == *argv[i]))) {
  1250.             switch (*(argv[i] + 1)) {
  1251.  
  1252.             case 'd':
  1253.             case 'D':
  1254.                 disp_level = atoi (argv[i] + 2);
  1255.                 break;
  1256. #if    0
  1257.             case 'e':
  1258.             case 'E':
  1259.                 e_option = !0;
  1260.                 break;
  1261. #endif
  1262.             case 'n':
  1263.             case 'N':
  1264.                 n_option = !0;
  1265.                 break;
  1266.  
  1267.             case 's':
  1268.             case 'S':
  1269.                 save_file = argv[i] + 2;
  1270.                 break;
  1271.  
  1272.             case 'x':
  1273.             case 'X':
  1274.                 xsp_mode_num = atoi (argv[i] + 2);
  1275.                 break;
  1276.  
  1277.             case 'y':
  1278.             case 'Y':
  1279.                 y_option = atoi (argv[i] + 2) - 1;
  1280.                 if (y_option + 1 > STAGES)
  1281.                     y_option = STAGES - 1;
  1282.                 break;
  1283.  
  1284.             case 'z':
  1285.             case 'Z':
  1286.                 z_option = atoi (argv[i] + 2);
  1287.                 if (z_option < 1)
  1288.                     z_option = 1;
  1289. #ifndef DEBUG
  1290.                 if (z_option > 9)
  1291.                     z_option = 9;
  1292. #endif
  1293.                 break;
  1294.  
  1295.             default:
  1296.                 Usage ();
  1297.                 return (-1);
  1298.             }
  1299.         } else {
  1300.         }
  1301.     }
  1302.  
  1303.  
  1304.     if ((y_option == 0) && (z_option == 3))
  1305.         standard_play = !0;
  1306.     else
  1307.         standard_play = 0;
  1308.  
  1309.     ReadHighScore (save_file);
  1310.     Init ();
  1311.  
  1312.     do {
  1313.         switch (Title ()){
  1314.         case SELECT_START:
  1315.             replay_flag = REPLAY_NON;
  1316.             Game ();
  1317.             break;
  1318.         case SELECT_REPLAY_BEFORE:
  1319.             if ((standard_play) && (replay_data_size != 0)) {
  1320.                 replay_flag = REPLAY_BEFORE;
  1321.                 Game ();
  1322.             }
  1323.             break;
  1324.         case SELECT_REPLAY_HIGH:
  1325.             if ((standard_play) && (high_score_replay_data_size != 0)) {
  1326.                 replay_flag = REPLAY_HIGH;
  1327.                 Game ();
  1328.             }
  1329.             break;
  1330.         case SELECT_RANKING:
  1331.             Ranking ();
  1332.             WaitTime (55 * 10);
  1333.             break;
  1334.         case SELECT_EXIT:
  1335.         default:
  1336.             exit_flag = !0;
  1337.             break;
  1338.         }
  1339.     } while (exit_flag == 0);
  1340.  
  1341.     Tini ();
  1342.     WriteHighScore (save_file);
  1343.  
  1344.     return (0);
  1345. }
  1346.